package com.hydl.power.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.hydl.power.mapper.OrderDeliveryMapper;
import com.hydl.power.mapper.PowerRoomMapper;
import com.hydl.power.mapper.ProtectDeviceMapper;
import com.hydl.power.mapper.WorkOrderMapper;
import com.hydl.power.pojo.OrderDelivery;
import com.hydl.power.pojo.PowerRoom;
import com.hydl.power.pojo.ProtectData;
import com.hydl.power.pojo.ProtectDevice;
import com.hydl.power.pojo.ProtectDeviceExample;
import com.hydl.power.pojo.WorkOrder;
import com.hydl.power.service.ProtectDeviceService;
import com.hydl.power.utils.IdUtil;

import lombok.extern.log4j.Log4j2;

/**
 * @author miss
 * @description 综保设备
 * @date 2023-01-04
 */
@Log4j2
@Service
public class ProtectDeviceServiceImpl implements ProtectDeviceService {

    private static final Map<String, String> SWITCH_MAP = new HashMap<String, String>() {{
        put("circuitBreakerSwitchOnPosition", "断路器合位置");
        put("circuitBreakerTripPosition", "断路器跳位置");
        put("remoteLocation", "远方位置");
        put("springNotStoreEnergy", "弹簧未储能");
        put("lightGasSignal", "轻瓦斯信号");
        put("highTemperatureSignal", "温度高信号");
        put("heavyGasSignal", "重瓦斯信号");
        put("overtemperatureTripSignal", "超温跳闸信号");
        put("groundingSwitchSignal", "接地刀闸信号");
        put("temperatureControllerFault", "温控器故障");
        put("input1", "开入1");
        put("input2", "开入2");
        put("var12", "变量12");
        put("var13", "变量13");
        put("var14", "变量14");
        put("var15", "变量15");
        put("quickBreakActionEventSign", "速断动作事件标志");
        put("overcurrent1", "过流1");
        put("overcurrent2", "过流2");
        put("inverseTimeOverload", "反时限过负荷");
        put("hvSideZeroSeqOvercurrent", "高压侧零序过流");
        put("lvSideInverseTimeZeroSeqOvercurrent", "低压侧反时限零序过流");
        put("noumenonTrip", "本体跳闸");
        put("controlFault", "控故障");
        put("ptDisconnection", "PT断线");
        put("inverseTimeOverloadWarning", "反时限过负荷预警");
        put("reserved", "保留");
        put("inverseTimeOverloadAlarm", "反时限过负荷告警");
        put("overvoltageProtection", "过压保护");
        put("voltageLossProtection", "失压保护");
        put("var30", "变量30");
        put("var31", "变量31");
        put("remoteSwitchOn", "遥控合");
        put("remoteSwitchOff", "遥控分");
        put("localSwitchOn", "就地合");
        put("localSwitchOff", "就地分");
        put("hvSideZeroSeqOvercurrentAlarm", "高压侧零序过流告警");
        put("lvSideZeroSeqOvercurrentAlarm", "低压侧零序过流告警");
        put("var38", "变量38");
        put("var39", "变量39");
        put("var40", "变量40");
        put("var41", "变量41");
        put("var42", "变量42");
        put("var43", "变量43");
        put("var44", "变量44");
        put("var45", "变量45");
        put("alarmTotalSignal", "告警总信号");
        put("accidentTotalSignal", "事故总信号");
    }};

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProtectDeviceMapper protectDeviceMapper;
    @Autowired
    private WorkOrderMapper workOrderMapper;
    @Autowired
    private OrderDeliveryMapper orderDeliveryMapper;
    @Autowired
    private PowerRoomMapper powerRoomMapper;

    @Override
    public int insert(ProtectDevice protectDevice) {
        return protectDeviceMapper.insertSelective(protectDevice);
    }

    @Override
    public int delete(int id) {
        ProtectDeviceExample example = new ProtectDeviceExample();
        ProtectDeviceExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(id);
        return protectDeviceMapper.deleteByExample(example);
    }

    @Override
    public int update(ProtectDevice protectDevice) {
        ProtectDeviceExample example = new ProtectDeviceExample();
        ProtectDeviceExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(protectDevice.getId());
        return protectDeviceMapper.updateByExampleSelective(protectDevice, example);
    }

    @Override
    public ProtectDevice load(int id) {
        ProtectDeviceExample example = new ProtectDeviceExample();
        ProtectDeviceExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(id);
        List<ProtectDevice> protectDeviceList = protectDeviceMapper.selectByExample(example);
        return CollectionUtils.isEmpty(protectDeviceList) ? null : protectDeviceList.get(0);
    }

    @Override
    public PageInfo<ProtectDevice> pageList(int pageNum, int pageSize, ProtectDevice protectDevice) {
        ProtectDeviceExample example = new ProtectDeviceExample();
        // ProtectDeviceExample.Criteria criteria = example.createCriteria();
        // criteria.andIdEqualTo(protectDevice.getId());
        List<ProtectDevice> pageList = protectDeviceMapper.selectPage(pageNum, pageSize);
        return new PageInfo<>(pageList);
    }

    @Override
    public List<ProtectDevice> query(ProtectDevice protectDevice) {
        ProtectDeviceExample example = new ProtectDeviceExample();
        ProtectDeviceExample.Criteria criteria = example.createCriteria();
        criteria.andPowerroomIdEqualTo(protectDevice.getPowerroomId());
        return protectDeviceMapper.selectByExample(example);
    }

    /**
     * 综保告警
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void protectAlarm() throws Exception {
        List<ProtectDevice> protectDeviceList = protectDeviceMapper.selectByExample(new ProtectDeviceExample());
        if (CollectionUtils.isEmpty(protectDeviceList)) {
            return;
        }
        Map<String, PowerRoom> powerRoomMap = powerRoomMapper.all()
            .stream()
            .collect(Collectors.toMap(PowerRoom::getRoomId, e -> e, (a, b) -> b));
        //todo 每个设备的的deviceId是否唯一
        List<OrderDelivery> orderDeliveryList = orderDeliveryMapper.getList();
        Map<String, List<OrderDelivery>> collect = orderDeliveryList.stream()
            .collect(Collectors.groupingBy(OrderDelivery::getDeviceId));


        for (ProtectDevice device : protectDeviceList) {
            PowerRoom powerRoom = powerRoomMap.get(device.getPowerroomId() + "");
            Object protectData = redisTemplate.opsForValue()
                .get(device.getDeviceId());
            if (protectData == null) {
                //todo 在线离线判断 更新device的alarm字段
                log.error("[{}]缓存数据为空", device.getDeviceId());
                // ProtectDevice record = new ProtectDevice();
                // ProtectDeviceExample example = new ProtectDeviceExample();
                // ProtectDeviceExample.Criteria criteria = example.createCriteria();
                // criteria.andIdEqualTo(record.getId());
                // protectDeviceMapper.updateByExampleSelective(record, example);
                OrderDelivery orderDelivery = new OrderDelivery();
                orderDelivery.setOrderDeliveryId(IdUtil.getRandomString(8));
                orderDelivery.setOrderTypes(1);
                orderDelivery.setRank(1);
                orderDelivery.setFault("通讯中断");
                orderDelivery.setFaultTime(new Date());
                orderDelivery.setFaultTypes(4);
                //工单状态  1待派送 2待处理(派送工单) 3处理中 4 忽略工单(以忽略) 5 以结束
                orderDelivery.setOrderStatus(3);
                //是否告警 1 告警 2 不告警
                orderDelivery.setFlag(1);
                if (powerRoom != null) {
                    orderDelivery.setAreaId(powerRoom.getAreaId());
                    orderDelivery.setAreaName(powerRoom.getAreaName());
                }
                orderDelivery.setProjectId(device.getProjectId() + "");
                orderDelivery.setProjectName(device.getProjectName());
                orderDelivery.setRoomId(device.getPowerroomId() + "");
                orderDelivery.setRoomName(device.getPowerroomName());
                orderDelivery.setDeviceId(device.getDeviceId());
                orderDelivery.setDeviceName(device.getDeviceName());
                // orderDelivery.setDeviceAddress(device.getDeviceAddress());
                orderDelivery.setSn(device.getGatewaySn());

                //判断是否存在对应的告警，存在则忽略
                boolean existOrderDelivery = false;
                List<OrderDelivery> deliveryList = collect.get(device.getDeviceId());
                if (CollectionUtils.isNotEmpty(deliveryList)) {
                    for (OrderDelivery delivery : deliveryList) {
                        if (Objects.equals(delivery.getDeviceId(), orderDelivery.getDeviceId())
                            && Objects.equals(delivery.getFault(), orderDelivery.getFault())
                            && (delivery.getOrderStatus() == 1 || delivery.getOrderStatus() == 2 || delivery.getOrderStatus() == 3)) {
                            existOrderDelivery = true;
                            break;
                        }
                    }
                }
                if (existOrderDelivery){
                    continue;
                }

                int insert = orderDeliveryMapper.insert(orderDelivery);
                // deviceMapper.updateDeviceAlarmByDeviceId(temperatureDevice.getDeviceId(),0,1);

                //推送
                // List<String> clientIdList = pushMapper.getClientId(orderDelivery.getProjectId());
                // PushUtils.sendMessage(clientIdList, orderDelivery.getRoomName(), orderDelivery.getDeviceName(), orderDelivery.getFault());
                //
                // List<Marketing> marketings = marketingMapper.queryMarketingByprojectId(temperatureDevice.getProjectId());

                //创建工单
                WorkOrder workOrder = new WorkOrder();
                workOrder.setOrderDeliveryId(orderDelivery.getOrderDeliveryId());
                workOrder.setOrderTypes(1);
                workOrder.setRank(1);
                workOrder.setFault("通讯中断");
                workOrder.setFaultTime(new Date());
                workOrder.setFaultTypes(4);
                workOrder.setOrderStatus(1);
                workOrder.setFlag(1);
                if (powerRoom != null) {
                    orderDelivery.setAreaId(powerRoom.getAreaId());
                    orderDelivery.setAreaName(powerRoom.getAreaName());
                }
                workOrder.setProjectId(device.getProjectId() + "");
                workOrder.setProjectName(device.getProjectName());
                workOrder.setRoomId(device.getPowerroomId() + "");
                workOrder.setRoomName(device.getPowerroomName());
                workOrder.setDeviceId(device.getDeviceId());
                workOrder.setDeviceName(device.getDeviceName());
                // workOrder.setDeviceAddress(temperatureDevice.getDeviceAddress());
                workOrder.setSn(device.getGatewaySn());
                workOrder.setAffirmStatus(2);
                workOrderMapper.addWorkOrder(workOrder);
            } else {
                //todo 同时多个告警

                // ProtectData data = JSONObject.parseObject(protectData.toString(), ProtectData.class);
                JSONObject jsonObject = JSONObject.parseObject(protectData.toString());
                Set<String> faultSet = new HashSet<>();
                for (Map.Entry<String, String> entry : SWITCH_MAP.entrySet()) {
                    String k = entry.getKey();
                    String v = entry.getValue();
                    //todo 脏数据，不存在这个key时continue
                    if (!jsonObject.containsKey(k)){
                        continue;
                    }
                    if (!"0".equals(jsonObject.getString(k))) {
                        faultSet.add(v);
                    }
                }
                if (CollectionUtils.isEmpty(faultSet)){
                    continue;
                }
                for (String fault : faultSet) {
                    log.error("[{}]发生异常:{}", device.getDeviceId(), fault);
                    // ProtectDevice record = new ProtectDevice();
                    // ProtectDeviceExample example = new ProtectDeviceExample();
                    // ProtectDeviceExample.Criteria criteria = example.createCriteria();
                    // criteria.andIdEqualTo(record.getId());
                    // protectDeviceMapper.updateByExampleSelective(record, example);
                    OrderDelivery orderDelivery = new OrderDelivery();
                    orderDelivery.setOrderDeliveryId(IdUtil.getRandomString(8));
                    orderDelivery.setOrderTypes(1);
                    orderDelivery.setRank(1);
                    // orderDelivery.setFault("通讯中断");
                    orderDelivery.setFault(fault);
                    orderDelivery.setFaultTime(new Date());
                    orderDelivery.setFaultTypes(4);
                    //工单状态  1待派送 2待处理(派送工单) 3处理中 4 忽略工单(以忽略) 5 以结束
                    orderDelivery.setOrderStatus(3);
                    //是否告警 1 告警 2 不告警
                    orderDelivery.setFlag(1);
                    if (powerRoom != null) {
                        orderDelivery.setAreaId(powerRoom.getAreaId());
                        orderDelivery.setAreaName(powerRoom.getAreaName());
                    }
                    orderDelivery.setProjectId(device.getProjectId() + "");
                    orderDelivery.setProjectName(device.getProjectName());
                    orderDelivery.setRoomId(device.getPowerroomId() + "");
                    orderDelivery.setRoomName(device.getPowerroomName());
                    orderDelivery.setDeviceId(device.getDeviceId());
                    orderDelivery.setDeviceName(device.getDeviceName());
                    // orderDelivery.setDeviceAddress(device.getDeviceAddress());
                    orderDelivery.setSn(device.getGatewaySn());

                    //判断是否存在对应的告警，存在则忽略
                    boolean existOrderDelivery = false;
                    List<OrderDelivery> deliveryList = collect.get(device.getDeviceId());
                    if (CollectionUtils.isNotEmpty(deliveryList)) {
                        for (OrderDelivery delivery : deliveryList) {
                            if (Objects.equals(delivery.getDeviceId(), orderDelivery.getDeviceId())
                                && Objects.equals(delivery.getFault(), orderDelivery.getFault())
                                && (delivery.getOrderStatus() == 1 || delivery.getOrderStatus() == 2 || delivery.getOrderStatus() == 3)) {
                                existOrderDelivery = true;
                                break;
                            }
                        }
                    }
                    if (existOrderDelivery){
                        continue;
                    }

                    int insert = orderDeliveryMapper.insert(orderDelivery);
                    // deviceMapper.updateDeviceAlarmByDeviceId(temperatureDevice.getDeviceId(),0,1);

                    //推送
                    // List<String> clientIdList = pushMapper.getClientId(orderDelivery.getProjectId());
                    // PushUtils.sendMessage(clientIdList, orderDelivery.getRoomName(), orderDelivery.getDeviceName(), orderDelivery.getFault());
                    //
                    // List<Marketing> marketings = marketingMapper.queryMarketingByprojectId(temperatureDevice.getProjectId());

                    //创建工单
                    WorkOrder workOrder = new WorkOrder();
                    workOrder.setOrderDeliveryId(orderDelivery.getOrderDeliveryId());
                    workOrder.setOrderTypes(1);
                    workOrder.setRank(1);
                    workOrder.setFault(fault);
                    workOrder.setFaultTime(new Date());
                    workOrder.setFaultTypes(4);
                    workOrder.setOrderStatus(1);
                    workOrder.setFlag(1);
                    if (powerRoom != null) {
                        workOrder.setAreaId(powerRoom.getAreaId());
                        workOrder.setAreaName(powerRoom.getAreaName());
                    }
                    workOrder.setProjectId(device.getProjectId() + "");
                    workOrder.setProjectName(device.getProjectName());
                    workOrder.setRoomId(device.getPowerroomId() + "");
                    workOrder.setRoomName(device.getPowerroomName());
                    workOrder.setDeviceId(device.getDeviceId());
                    workOrder.setDeviceName(device.getDeviceName());
                    // workOrder.setDeviceAddress(temperatureDevice.getDeviceAddress());
                    workOrder.setSn(device.getGatewaySn());
                    workOrder.setAffirmStatus(2);
                    workOrderMapper.addWorkOrder(workOrder);
                }

            }
        }
    }

}